﻿using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Json;
using Abp.Linq.Extensions;
using ARchGL.Platform.Authorization.Users;
using ARchGL.Platform.Core;
using ARchGL.Platform.Dto;
using ARchGL.Platform.Dtos;
using ARchGL.Platform.FileServer;
using ARchGL.Platform.Juneng.ViewDtos;
using ARchGL.Platform.Sessions;
using Castle.Core.Logging;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ARchGL.Platform.Application
{
    /// <summary>
    /// 各种业务相关扩展
    /// </summary>
    public static class AppServiceExtension
    {
        #region 通知

        /// <summary>
        /// 分发通知至用户
        /// </summary>
        /// <param name="repository">仓储实例</param>
        /// <param name="noticeId">通知标识</param>
        /// <param name="userId">用户标识</param>
        /// <param name="currentUserId">当前登录用户标识</param>
        /// <param name="status">状态：1已读、2未读，自己给自己发时默认已读</param>
        /// <returns></returns>
        public static async Task InsertAsync(this IRepository<NoticesUsers, Guid> repository, Guid noticeId, Guid userId, Guid? currentUserId, int status = 2)
        {
            var entity = new NoticesUsers
            {
                NoticeId = noticeId,
                UserId = userId,
                Status = status,
                CreatorUserId = currentUserId
            };
            await repository.InsertAsync(entity);
        }

        /// <summary>
        /// 将公告分发到指定用户
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="noticeId">通知标识</param>
        /// <param name="currentUserId">当前用户标识</param>
        /// <param name="userIdList">接收用户标识</param>
        /// <returns></returns>
        public static async Task InsertAsync(this IRepository<NoticesUsers, Guid> repository, Guid noticeId, Guid? currentUserId, params List<Guid>[] userIdList)
        {
            var idList = new List<Guid>();
            foreach (var item in userIdList)
            {
                if (item == null) continue;
                idList.AddRange(item);
            }

            foreach (var id in idList.Distinct())
            {
                await repository.InsertAsync(noticeId, id, currentUserId, id == currentUserId ? 1 : 2);
            }
        }

        #endregion

        #region 附件相关

        /// <summary>
        /// 获取附件地址集合
        /// </summary>
        /// <param name="list"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static List<string> GetUrls(this List<Attachments> list, Guid id)
        {
            return list.Where(x => x.PrimaryId == id).Select(x => x.Url).ToList();
        }

        /// <summary>
        /// 获取附件地址集合
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static List<string> GetUrls(this List<Attachments> list)
        {
            return list.Select(x => x.Url).ToList();
        }

        /// <summary>
        /// 保存附件信息
        /// </summary>
        /// <param name="repository">仓储实例</param>
        /// <param name="list">附件数据集合</param>
        /// <param name="primaryId">主键标识</param>
        /// <returns></returns>
        public static async Task InsertAsync(this IRepository<Attachments, Guid> repository, List<AttachmentsInput> list, Guid primaryId)
        {
            if (list == null) return;

            foreach (var item in list)
            {//保存附件
                var sca = new Attachments
                {
                    PrimaryId = primaryId,
                    FileId = item.FileId,
                    Name = item.Name,
                    Url = item.Url
                };
                await repository.InsertAsync(sca);
            }
        }

        #endregion

        #region 文件库相关
        /// <summary>
        /// 返回所有目录及文件Id:含parentIdList
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="currentUserId"></param>
        /// <param name="parentIdList"></param>
        /// <param name="allResultList"></param>
        /// <returns></returns>
        public static async Task<List<Guid>> GetAllChildListWithParentIdAsync(this IRepository<DocumentLibrarys, Guid> repository, Guid? currentUserId, List<Guid> parentIdList, List<Guid> allResultList = null)
        {
            if (allResultList == null) allResultList = new List<Guid>();

            var list = await repository.GetAll().Where(x => x.CreatorUserId == currentUserId && parentIdList.Contains(x.ParentId.Value)).ToListAsync();

            if (list.Any())
                allResultList.AddRange(list.Select(t => t.Id));

            var folderIdList = list.Where(x => x.IsFolder).Select(x => x.Id).ToList();
            if (folderIdList != null && folderIdList.Count > 0)
            {
                allResultList = await GetAllChildListWithParentIdAsync(repository, currentUserId, folderIdList, allResultList);
            }
            return allResultList;
        }

        /// <summary>
        /// 批量添加检查项
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static async Task<List<DocumentLibrarys>> BatchInsert(this IRepository<DocumentLibrarys, Guid> repository, List<DocumentLibrarys> input)
        {
            List<DocumentLibrarys> result = new List<DocumentLibrarys>();
            if (input != null)
            {
                foreach (var item in input)
                {
                    item.Id = item.Id == Guid.Empty ? Guid.NewGuid() : item.Id;
                    result.Add(await repository.InsertAsync(item));
                }
                //input.ForEach(async item =>
                //{
                //  );
                //});
            }
            return result;
        }

        /// <summary>
        /// 项目工程模板
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static List<ProjectCategoryTemplate> BatchInsert(this IRepository<ProjectCategoryTemplate, Guid> repository, List<ProjectCategoryTemplate> input)
        {
            List<ProjectCategoryTemplate> result = new List<ProjectCategoryTemplate>();
            if (input != null)
            {
                foreach (var item in input)
                {
                    result.Add(repository.Insert(item));
                }
            }
            return result;
        }

        #endregion

        #region 用户相关

        /// <summary>
        /// 获取用户标识
        /// </summary>
        /// <param name="userIdList"></param>
        /// <param name="list"></param>
        public static void AddRange(this List<Guid?> userIdList, IEnumerable<string> list)
        {
            foreach (var item in list)
            {
                userIdList.AddRange(item);
            }
        }

        /// <summary>
        /// 获取用户标识
        /// </summary>
        /// <param name="userIdList"></param>
        /// <param name="input"></param>
        public static void AddRange(this List<Guid?> userIdList, string input)
        {
            if (input.IsNullOrWhiteSpace()) return;
            var values = ((JArray)JsonConvert.DeserializeObject(input)).Values();
            foreach (var c in values)
            {//将筛选出来的用户标识储存到 UserIdList 变量中
                Guid.TryParse(c.ToString(), out var id);
                userIdList.Add(id);
            }
        }

        /// <summary>
        /// 获取用户名
        /// </summary>
        /// <param name="list"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetNameOrEmpty(this List<User> list, Guid? input)
        {
            var entity = list.FirstOrDefault(x => x.PrimaryId == input);
            return entity?.Name ?? string.Empty;
        }

        /// <summary>
        /// 获取用户名集合
        /// </summary>
        /// <param name="list"></param>
        /// <param name="input">用户标识集合</param>
        /// <returns></returns>
        public static List<string> GetNameList(this List<User> list, List<Guid> input)
        {
            return list.Where(x => input.Contains(x.PrimaryId)).Select(x => x.Name).ToList();
        }

        /// <summary>
        /// 获取用户名集合
        /// </summary>
        /// <param name="list"></param>
        /// <param name="input">用户标识 string 集合</param>
        /// <returns></returns>
        public static List<string> GetNameList(this List<User> list, IEnumerable<string> input)
        {
            var idList = new List<Guid>();
            foreach (var item in input) idList.AddRange(item);
            return list.Where(x => idList.Contains(x.PrimaryId)).Select(x => x.Name).ToList();
        }

        /// <summary>
        /// 获取用户名集合
        /// </summary>
        /// <param name="list"></param>
        /// <param name="input">用户标识 string 集合</param>
        /// <returns></returns>
        public static List<string> GetNameList(this List<User> list, string input)
        {
            if (input.IsNullOrWhiteSpace()) return new List<string>();
            var userIdList = ((JArray)JsonConvert.DeserializeObject(input)).Values().Select(c => Guid.Parse(c.ToString()));
            return list.Where(x => userIdList.Contains(x.PrimaryId)).Select(x => x.Name).ToList();
        }

        #endregion

        #region 项目与项目用户相关

        /// <summary>
        /// 获取项目名称
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetNameOrEmpty(this IRepository<Projects, Guid> repository, Guid input)
        {
            var user = repository.FirstOrDefault(input);
            return user?.Name ?? string.Empty;
        }

        /// <summary>
        /// 删除系统用户时，同时将用户从所有项目中删除
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static async Task RemoveUserOnProjectByUserId(this IRepository<ProjectUsers, Guid> repository, Guid input)
        {
            var list = repository.GetAll().Where(x => x.UserId == input);
            foreach (var item in list)
            {
                await repository.DeleteAsync(item);
            }
        }

        #endregion

        #region 项目模型

        /// <summary>获取待转换模型信息</summary>
        public static async Task<List<ProjectModelInfo>> GetConvertModelList(this IRepository<ProjectModels, Guid> repository, ConvertModelsInput input)
        {
            var list = await repository.GetAllListAsync(x => x.ProjectId == input.ProjectId && x.ModelGroupId == input.ModelGroupId && x.Status < 2);
            return GetConvertModelList(list);
        }

        private static List<ProjectModelInfo> GetConvertModelList<T>(List<T> list) where T : ModelBase
        {
            return new List<ProjectModelInfo>(list.Select(x => new ProjectModelInfo
            {
                Id = x.Id,
                Name = x.FileName,
                Path = x.Path,
                Type = x.Type,
                Hash = x.Hash,
                ModelGroupId = x.ModelGroupId,
                TaskId = x.TaskId,
                ConvertStatus = x.Status, //当前转换状态，供后面判断使用
                CreatedUserId = x.SSOCreatorUserId
            }));
        }

        /// <summary>获取待转换模型信息</summary>
        public static async Task<List<ProjectModelInfo>> GetConvertModelList(this IRepository<ProjectDrawings, Guid> repository, ConvertModelsInput input)
        {
            var list = await repository.GetAllListAsync(x => x.ProjectId == input.ProjectId && x.ModelGroupId == input.ModelGroupId && x.Status < 2);
            return GetConvertModelList(list);
        }

        /// <summary>
        /// 发起转换请求（向文件服务）
        /// </summary>
        /// <param name="list">待转换 模型/图纸 数据</param>
        /// <param name="config">配置文件实例，用于获取文件服务主机地址</param>
        /// <param name="modelGroupId">场景标识</param>
        /// <param name="projectId">项目标识</param>
        /// <param name="logger">日志实例</param>
        /// <returns></returns>
        public static async Task<IRestResponse> RequestConvertModel(this List<ProjectModelInfo> list, IConfigurationRoot config, Guid modelGroupId, Guid projectId, ILogger logger)
        {
            if (!list.Any()) return null; //没有需要转换的模型，请先上传模型
            var request = new RestRequest($"file/api/v1/fileConvert/convert-model/{modelGroupId}", Method.POST, DataFormat.Json);
            request.AddHeader("TenantId", Convert.ToBase64String(Encoding.UTF8.GetBytes(projectId.ToString())));
            request.AddHeader("Authorization", RefreshTokenService.GetAccessToken());
            request.AddJsonBody(list);
            var client = new RestClient(config["App:FileServerRootAddress"]); //文件服务
            logger.Info($"\r\n#################################   调用转换输入参数：{JsonConvert.SerializeObject(list)}");
            var response = client.Execute(request);
            logger.Info($"\r\n#################################   调用转换：{response.StatusCode} " + response.Content);
            return response;
        }

        /// <summary>
        /// 发起转换进度查询请求（向文件服务）
        /// </summary>
        /// <param name="list"></param>
        /// <param name="config"></param>
        /// <param name="modelGroupId"></param>
        /// <param name="projectId"></param>
        /// <param name="logger"></param>
        /// <returns></returns>
        public static async Task<IRestResponse[]> RequestConvertProcess(this List<ProjectModelInfo> list, IConfigurationRoot config, Guid modelGroupId, Guid projectId, ILogger logger)
        {
            var request = new RestRequest($"file/api/v1/fileConvert/convert-process", Method.GET);
            request.AddHeader("TenantId", Convert.ToBase64String(Encoding.UTF8.GetBytes(projectId.ToString())));
            request.AddHeader("Authorization", RefreshTokenService.GetAccessToken());
            var rsult = new IRestResponse[list.Count];
            //foreach (var item in list)
            for (int i = 0; i < list.Count; i++)
            {
                var item = list[i];
                request.AddParameter("modelGroupId", modelGroupId);
                request.AddParameter("taskId", item.TaskId);
                var client = new RestClient(config["App:FileServerRootAddress"]); //文件服务
                logger.Info($"\r\n#################################   调用转换输入参数：{JsonConvert.SerializeObject(list)}");
                var response = client.Execute(request);
                rsult[i] = response;
                logger.Info($"\r\n#################################   调用转换：{response.StatusCode} " + response.Content);
            }
            return rsult;
        }

        #endregion

        #region 巡检 与 自检

        private static long CheckNumber = 0; //巡检编号
        private static long SelfCheckNumber = 0; //自检编号
        /// <summary>
        /// 获取巡检编号
        /// </summary>
        /// <param name="repository"></param>
        /// <returns></returns>
        public static async Task<long> GetNumberAsync(this IRepository<SecurityChecks, Guid> repository)
        {
            if (CheckNumber == 0)
            {
                var count = await repository.LongCountAsync();
                if (count == 0) return 1;
                CheckNumber = await repository.GetAll().Select(x => x.Number).MaxAsync();
            }
            return await Task.FromResult(++CheckNumber);
        }

        /// <summary>
        /// 获取自检编号
        /// </summary>
        /// <param name="repository"></param>
        /// <returns></returns>
        public static async Task<long> GetNumberAsync(this IRepository<SelfChecks, Guid> repository)
        {
            if (SelfCheckNumber == 0)
            {
                var count = await repository.LongCountAsync();
                if (count == 0) return 1;
                SelfCheckNumber = await repository.GetAll().Select(x => x.Number).MaxAsync();
            }
            return await Task.FromResult(++SelfCheckNumber);
        }

        /// <summary>
        /// 更新巡检状态
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="entity">巡检</param>
        /// <param name="status"></param>
        /// <returns></returns>
        public static async Task UpdateStatusAsync(this IRepository<SecurityChecks, Guid> repository, SecurityChecks entity, EnumCheckAndFeedbackStatus status)
        {
            entity.Status = status;
            await repository.UpdateAsync(entity);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static async Task<SecurityChecks> GetByIdAsync(this IRepository<SecurityChecks, Guid> repository, Guid input)
        {
            var entity = await repository.FirstOrDefaultAsync(input);
            //;if(entity == null ) if (entity == null) throw new UserFriendlyException(L("TheItemDoesNotExist"), L("PleaseRefreshThePageAndTryAgain"));
            return entity;
        }

        #endregion

        #region 检查项 与 检查性质

        /// <summary>
        /// 获取 检查项/检查性质 标识
        /// </summary>
        /// <param name="checkItemIdList"></param>
        /// <param name="input"></param>
        public static void AddRange1(this List<Guid> checkItemIdList, string input)
        {
            if (input.IsNullOrWhiteSpace()) return;
            var values = ((JArray)JsonConvert.DeserializeObject(input)).Values();
            foreach (var c in values)
            {//将筛选出来的 检查项/检查性质 标识储存到 checkItemIdList 变量中
                checkItemIdList.Add(Guid.Parse(c.ToString()));
            }
        }

        /// <summary>
        /// 获取 检查项/检查性质 标识
        /// </summary>
        /// <param name="checkItemIdList"></param>
        /// <param name="array"></param>
        public static void AddRange(this List<Guid> checkItemIdList, params string[] array)
        {
            foreach (var str in array)
            {
                var values = ((JArray)JsonConvert.DeserializeObject(str)).Values();
                foreach (var item in values)
                {//将筛选出来的 检查项/检查性质 标识储存到 checkItemIdList 变量中
                    checkItemIdList.Add(Guid.Parse(item.ToString()));
                }
            }
        }

        /// <summary>
        /// 获取 检查项/检查性质 名称集合
        /// </summary>
        /// <param name="list"></param>
        /// <param name="input">用户标识 string 数组</param>
        /// <returns></returns>
        public static List<string> GetNameList(this List<SecurityCheckItems> list, string input)
        {
            if (input.IsNullOrWhiteSpace()) return new List<string>();
            var userIdList = ((JArray)JsonConvert.DeserializeObject(input)).Values().Select(c => Guid.Parse(c.ToString()));
            return list.Where(x => userIdList.Contains(x.Id)).Select(x => x.Name).ToList();
        }

        /// <summary>
        /// 获取 检查项/检查性质 名称
        /// </summary>
        /// <param name="list"></param>
        /// <param name="input">用户标识 string 数组</param>
        /// <returns></returns>
        public static string GetNameOrEmpty(this List<SecurityCheckItems> list, Guid input)
        {
            if (list == null || list.Count == 0) return string.Empty;
            return list.FirstOrDefault(x => x.Id == input)?.Name ?? string.Empty;
        }

        /// <summary>
        /// 获取检查项名称
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetNameOrEmpty(this IRepository<SecurityCheckItems, Guid> repository, Guid input)
        {
            var entity = repository.FirstOrDefault(input);
            return entity?.Name ?? string.Empty;
        }

        /// <summary>
        /// 批量添加检查项
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static async Task<List<SecurityCheckItems>> BatchInsert(this IRepository<SecurityCheckItems, Guid> repository, List<SecurityCheckItems> input)
        {
            List<SecurityCheckItems> result = new List<SecurityCheckItems>();
            if (input != null)
            {
                input.ForEach(async item =>
                {
                    result.Add(await repository.InsertAsync(item));
                });
            }
            return result;
        }

        #endregion

        #region 部门

        /// <summary>
        /// 获取部门名称
        /// </summary>
        /// <param name="list"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetNameOrEmpty(this List<OrganizationUnitExtend> list, long? input)
        {
            var user = list.FirstOrDefault(x => x.Id == input);
            return user?.DisplayName ?? string.Empty;
        }

        /// <summary>
        /// 获取部门名称
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static async Task<string> GetNameById(this IRepository<OrganizationUnitExtend, long> repository, long input)
        {
            var entity = await repository.FirstOrDefaultAsync(x => x.Id == input);
            return entity?.DisplayName;
        }

        /// <summary>
        /// 获取部门名称集合
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        public static async Task<List<string>> GetOrganizationUnitNames(this IRepository<OrganizationUnitExtend, long> repository, List<long> list)
        {
            var result = await repository.GetOrganizationUnitList(list);
            if (result == null) return null;
            return result.Select(x => x.DisplayName).ToList();
        }

        /// <summary>
        /// 获取部门集合
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        public static async Task<List<OrganizationUnitExtend>> GetOrganizationUnitList(this IRepository<OrganizationUnitExtend, long> repository, List<long> list)
        {
            if (list == null || list.Count == 0) return null;
            return await repository.GetAllListAsync(x => list.Contains(x.Id));
        }

        #endregion

        #region 时间范围查询

        /// <summary>
        /// 检查日期范围查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public static IQueryable<T> WhereCheckDateRange<T>(this IQueryable<T> query, DateTime?[] range) where T : EntityCheckDateBase
        {
            if (range == null || range.Length == 0) return query;
            CheckDateTimeRange(range);

            if (range.Length == 1)//只有开始时间，执行大于查询
                query = query.WhereIf(range[0].HasValue, x => x.CheckDate.Date >= range[0].Value.Date);

            if (range.Length == 2)//范围查询
                query = query.WhereIf(range[0].HasValue, x => x.CheckDate.Date >= range[0].Value.Date)
                    .WhereIf(range[1].HasValue, x => x.CheckDate.Date <= range[1].Value.Date);

            return query;
        }

        /// <summary>
        /// 创建时间范围查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public static IQueryable<T> WhereCreationTimeRange<T>(this IQueryable<T> query, DateTime?[] range) where T : EntityBase
        {
            if (range == null || range.Length == 0) return query;
            CheckDateTimeRange(range);

            if (range.Length == 1)//只有开始时间，执行大于查询
                query = query.WhereIf(range[0].HasValue, x => x.CreationTime.Date >= range[0].Value.Date);

            if (range.Length == 2)//范围查询
            {
                query = query.WhereIf(range[0].HasValue, x => x.CreationTime.Date >= range[0].Value.Date)
                    .WhereIf(range[1].HasValue, x => x.CreationTime.Date <= range[1].Value.Date);
            }

            return query;
        }

        public static IQueryable<T> WhereCreationTimeRange1<T>(this IQueryable<T> query, DateTime?[] range) where T : EntityCreatorUserIdBase
        {
            if (range == null || range.Length == 0) return query;
            CheckDateTimeRange(range);

            if (range.Length == 1)//只有开始时间，执行大于查询
                query = query.WhereIf(range[0].HasValue, x => x.CreationTime.Date >= range[0].Value.Date);

            if (range.Length == 2)//范围查询
            {
                query = query.WhereIf(range[0].HasValue, x => x.CreationTime.Date >= range[0].Value.Date)
                    .WhereIf(range[1].HasValue, x => x.CreationTime.Date <= range[1].Value.Date);
            }

            return query;
        }

        /// <summary>
        /// 升降机数据记录时间范围查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public static IQueryable<T> WhereLiftRecordTimeRange<T>(this IQueryable<T> query, DateTime?[] range) where T : QB_ProjectLifts
        {
            if (range == null || range.Length == 0) return query;
            CheckDateTimeRange(range);

            if (range.Length == 1)//只有开始时间，执行大于查询
                query = query.WhereIf(range[0].HasValue, x => x.RecordTime.HasValue && x.RecordTime.Value.Date >= range[0].Value.Date);

            if (range.Length == 2)//范围查询
                query = query.WhereIf(range[0].HasValue, x => x.RecordTime.HasValue && x.RecordTime.Value.Date >= range[0].Value.Date)
                    .WhereIf(range[1].HasValue, x => x.RecordTime.HasValue && x.RecordTime.Value.Date <= range[1].Value.Date);

            return query;
        }

        /// <summary>
        /// 塔吊数据记录时间范围查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public static IQueryable<T> WhereCraneRecordTimeRange<T>(this IQueryable<T> query, DateTime?[] range) where T : QB_ProjectCranes
        {
            if (range == null || range.Length == 0) return query;
            CheckDateTimeRange(range);

            if (range.Length == 1)//只有开始时间，执行大于查询
                query = query.WhereIf(range[0].HasValue, x => x.RecordTime.HasValue && x.RecordTime.Value.Date >= range[0].Value.Date);

            if (range.Length == 2)//范围查询
                query = query.WhereIf(range[0].HasValue, x => x.RecordTime.HasValue && x.RecordTime.Value.Date >= range[0].Value.Date)
                    .WhereIf(range[1].HasValue, x => x.RecordTime.HasValue && x.RecordTime.Value.Date <= range[1].Value.Date);

            return query;
        }

        private static void CheckDateTimeRange(DateTime?[] range)
        {
            if (range.Length == 2 && range[0].HasValue && range[1].HasValue)
                if (range[0] > range[1])
                {//开始时间大于结束时间时，交换变量
                    var temp = range[0];
                    range[0] = range[1];
                    range[1] = temp;
                }
        }

        /// <summary>
        /// 检查并修正时间范围字段
        /// </summary>
        /// <param name="range"></param>

        public static DateTime[] RangeDateTime(this DateTime[] range)
        {
            if (range.Length < 2)
                return range;

            if (range[0] > range[1])
            {//开始时间大于结束时间时，交换变量
                var temp = range[0];
                range[0] = range[1];
                range[1] = temp;
            }
            return range;
        }

        #endregion

        #region 千变事件最终时间查询

        public static DateTime GetQB_EventDate(this IRepository<QB_EventJobs, Guid> qb_eventJobsRepository, QB_EnumEventArg eventArg, DateTime defaultDate)
        {
            var obj = qb_eventJobsRepository.FirstOrDefault(t => t.EventArg == eventArg);
            if (obj == null)
            {
                obj = qb_eventJobsRepository.Insert(new QB_EventJobs
                {
                    Id = Guid.NewGuid(),
                    EventArg = eventArg,
                    CreationTime = DateTime.Now,
                    EventDate = defaultDate,
                    TenantId = 1,
                    IsFinish = false
                });
            }

            return obj.EventDate.Date;
        }

        /// <summary>
        /// 更新日期
        /// </summary>
        /// <param name="qb_eventJobsRepository"></param>
        /// <param name="eventArg"></param>
        /// <param name="newDate"></param>
        public static void UpdQB_EventDate(this IRepository<QB_EventJobs, Guid> qb_eventJobsRepository, QB_EnumEventArg eventArg, DateTime newDate)
        {
            qb_eventJobsRepository.Delete(t => t.EventArg == eventArg);
            qb_eventJobsRepository.Insert(new QB_EventJobs
            {
                Id = Guid.NewGuid(),
                EventArg = eventArg,
                CreationTime = DateTime.Now,
                EventDate = newDate,
                TenantId = 1,
                IsFinish = true
            });
        }

        #endregion

        #region 第三方设备

        /// <summary>获取塔吊统计 JSON 字符串</summary>
        public static string GetAvg(this List<TowerCranesRealDatas> list, Func<TowerCranesRealDatas, decimal> predicate)
        {
            var flag = list.Any();
            return new ReportAvg(
                flag ? list.Min(x => predicate(x)) : 0,
                flag ? list.Max(x => predicate(x)) : 0,
                flag ? list.Average(x => predicate(x)) : 0)
                .ToJsonString();
        }

        /// <summary>获取塔吊统计 JSON 字符串</summary>
        public static string GetEmptyAvg(this List<TowerCranesRealDatas> list)
        {
            return new ReportAvg().ToJsonString();
        }

        /// <summary>
        /// 获取塔吊实时数据集合
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="blackBoxId">设备标识</param>
        /// <param name="recordTime">数据时间</param>
        /// <returns></returns>
        public static async Task<List<TowerCranesRealDatas>> GetAllListAsync(this IRepository<TowerCranesRealDatas, Guid> repository, string blackBoxId, DateTime recordTime)
        {
            var query = repository.GetAll().Where(x => x.BlackBoxId == blackBoxId);
            if (DateTime.Now.Subtract(recordTime).TotalHours <= 24)
                query = query.Where(x => x.CreationTime.Date == recordTime.Date && x.CreationTime.Date.Hour < recordTime.Date.Hour);
            else query = query.Where(x => x.CreationTime.Date == recordTime.Date);

            return await Task.FromResult(query.OrderBy(x => x.CreationTime).ToList());
        }

        /// <summary>获取升降机统计 JSON 字符串</summary>
        public static string GetAvg(this List<HoistRealDatas> list, Func<HoistRealDatas, decimal> predicate)
        {
            var flag = list.Any();
            return new ReportAvg(
                flag ? list.Min(x => predicate(x)) : 0,
                flag ? list.Max(x => predicate(x)) : 0,
                flag ? list.Average(x => predicate(x)) : 0)
                .ToJsonString();
        }

        /// <summary>获取升降机统计 JSON 字符串</summary>
        public static string GetEmptyAvg(this List<HoistRealDatas> list)
        {
            return new ReportAvg().ToJsonString();
        }

        /// <summary>
        /// 获取塔吊实时数据集合
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="blackBoxId">设备标识</param>
        /// <param name="recordTime">数据时间</param>
        /// <returns></returns>
        public static async Task<List<HoistRealDatas>> GetAllListAsync(this IRepository<HoistRealDatas, Guid> repository, string blackBoxId, DateTime recordTime)
        {
            var query = repository.GetAll().Where(x => x.BlackBoxId == blackBoxId);
            if (DateTime.Now.Subtract(recordTime).TotalHours <= 24)
                query = query.Where(x => x.CreationTime.Date == recordTime.Date && x.CreationTime.Date.Hour < recordTime.Date.Hour);
            else query = query.Where(x => x.CreationTime.Date == recordTime.Date);

            return await Task.FromResult(query.OrderBy(x => x.CreationTime).ToList());
        }


        /// <summary>获取统计 JSON 字符串</summary>
        public static string GetAvg(this List<Environments> list, Func<Environments, decimal> predicate)
        {
            var flag = list.Any();
            return new ReportAvg(
                flag ? list.Min(x => predicate(x)) : 0,
                flag ? list.Max(x => predicate(x)) : 0,
                flag ? list.Average(x => predicate(x)) : 0)
                .ToJsonString();
        }

        /// <summary>
        /// 获取塔吊实时数据集合
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="code">安监备案号</param>
        /// <param name="recordTime">数据时间</param>
        /// <returns></returns>
        public static async Task<List<Environments>> GetAllListAsync(this IRepository<Environments, long> repository, string code, DateTime recordTime)
        {
            var query = repository.GetAll().Where(x => x.Code == code);

            if (DateTime.Now.Subtract(recordTime).TotalHours <= 24)
                query = query.Where(x => x.CreationTime.Date == recordTime.Date && x.CreationTime.Date.Hour <= recordTime.Date.Hour);
            if (DateTime.Now.Subtract(recordTime).Days > 1)
                query = query.Where(x => x.CreationTime.Date == recordTime.Date);
            else query = query.Where(x => x.CreationTime.Date == recordTime.Date);

            return await Task.FromResult(query.OrderBy(x => x.CreationTime).ToList());
        }

        #region 实名制

        /// <summary>
        /// 获取用户名
        /// </summary>
        /// <param name="list"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetNameOrEmpty(this List<TP_ProjectUsers> list, string input)
        {
            var entity = list.FirstOrDefault(x => x.UserId == input);
            return entity?.Name ?? string.Empty;
        }

        /// <summary>
        /// 获取团队名称
        /// </summary>
        /// <param name="list"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetNameOrEmpty(this List<Teams> list, Guid? input)
        {
            var entity = list.FirstOrDefault(x => x.Id == input);
            return entity?.Name ?? string.Empty;
        }

        /// <summary>
        /// 获取专业名称
        /// </summary>
        /// <param name="list"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetNameOrEmpty(this List<Majors> list, Guid? input)
        {
            var entity = list.FirstOrDefault(x => x.Id == input);
            return entity?.Name ?? string.Empty;
        }

        /// <summary>
        /// 获取注册信息名称
        /// </summary>
        /// <param name="list"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetGenderOrEmpty(this List<ProjectUsersRegister> list, string input)
        {
            var entity = list.FirstOrDefault(x => x.UserId == input);
            if (entity == null) return "-";
            else if (entity.Gender == 1) return "男";
            else if (entity.Gender == 2) return "女";
            else return "-";
        }

        #endregion

        #endregion
    }
}
